package com.chub.study.modules.controller;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;


/**
 * @author : chub
 * @version : V1.0.0
 * @fileName : FileDownloadController.java
 * @description : TODO
 * @createTime : 2024-05-28 19:37
 */
@RestController
public class FileDownloadController extends BaseController {


    /**
     * @param :
     * @return : ResponseEntity<Resource>
     * @description : 使用spring包下载返回，重点是使用ClassPathResource读取文件
     * @author : chub
     * @date : 2024-05-28 19:52
     */
    @GetMapping("/downloadTemplate")
    public ResponseEntity<Resource> downloadTemplate() throws IOException {
        // 假设应用部署后，classpath根目录下的相对路径映射到服务器文件系统中的实际位置
        Path filePath = Paths.get("src/main/resources/template/Template.dbf");

        // 如果应用打包成jar运行，则不能直接从文件系统读取，需要通过ClassLoader加载资源
        ClassPathResource resource = new ClassPathResource("template/Template.dbf");
        // 如果是可读的文件系统资源
        File file = resource.getFile();

        // 如果文件不存在或无法转换为File，请考虑使用resource.getInputStream()流式读取

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=Template.dbf");
        // 根据实际情况调整MIME类型
        headers.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");

        // 使用FileSystemResource或任何能包装文件输入流的对象
        return ResponseEntity.ok()
                .headers(headers)
                .body(new FileSystemResource(file));
    }

    /**
     * @param : null
     * @return : null
     * @description : 传统IO流下载返回
     * @author : chub
     * @date : 2024-05-28 19:52
     */
    @GetMapping("/downloadTemplate1")
    public void downloadTemplate1(HttpServletResponse response) throws IOException {
        // 如果应用打包成jar运行，则不能直接从文件系统读取，需要通过ClassLoader加载资源
        ClassPathResource resource = new ClassPathResource("template/Template.dbf");
        // 如果是可读的文件系统资源
        FileInputStream is = null;
        BufferedInputStream bs = null;
        OutputStream os = null;
        try {
            File file = resource.getFile();
            if (file.exists()) {
                //设置Headers
                response.setHeader("Content-Type", "application/octet-stream");
                //设置下载的文件的名称-该方式已解决中文乱码问题
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("导入模板.dbf", StandardCharsets.UTF_8.toString()));
                is = new FileInputStream(file);
                bs = new BufferedInputStream(is);
                os = response.getOutputStream();
                int len;
                byte[] buffer = new byte[1024];
                while ((len = bs.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
                os.flush();
                os.close();
                bs.close();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param : response
     * @return : void
     * @description : TODO
     * @author : chub
     * @date : 2024-05-28 19:52
     */

    @GetMapping("/downloadTemplate2")
    public void downloadTemplate2(HttpServletResponse response) throws IOException {

        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("/template/Template.dbf");
        Resource resource = resources[0];
        //设置Headers
        response.setHeader("Content-Type", "application/octet-stream");
        //设置下载的文件的名称-该方式已解决中文乱码问题
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("导入模板.dbf", StandardCharsets.UTF_8.toString()));
        try (InputStream inputStream = resource.getInputStream();
             OutputStream outputStream = response.getOutputStream()) {

            // 将输入流的数据写入响应的输出流
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            response.flushBuffer();
        }
    }


    @RequestMapping("/downloadfile")
    public void downloadfile(String filePath, String token, String name, HttpServletResponse response) throws IOException {
        //获得请求文件名
        if (!StringUtils.isEmpty(token)) {
            filePath = filePath + "&token=" + token;
        }
        URL getUrl = new URL(filePath);
        // 返回不同的URLConnection子类的对象，这里URL是一个http，因此实际返回的是HttpURLConnection
        HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
        // 进行连接，但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到
        connection.connect();
        // 取得输入流，并使用Reader读取
        BufferedInputStream reader = new BufferedInputStream(connection.getInputStream());
        ServletOutputStream out = response.getOutputStream();
        //处理文件中的乱码问题
        byte[] bytes = name.getBytes("UTF-8");
        String name1 = new String(bytes, "ISO-8859-1");
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/download");
        response.addHeader("Content-Disposition", "attachment;filename=" + name1);
        int len = 0;
        byte[] buffer = new byte[1024];
        while ((len = reader.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        //释放资源
        connection.disconnect();
        out.close();
    }


}
